import { Database, verbose } from "sqlite3";
export namespace SqlDB {
    export interface BaseData {
        [attr: string]: string | number;
    }
}
export class SqlDB<TableData> {
    public static typeVal(val: string | number) {
        if (typeof val === "string") {
            return `"${val}"`;
        }
        return val;
    }
    public static getCoupleList(obj: any, sepSymbol: string = "="): string[] {
        const coupleList: string[] = [];
        for (const attr in obj) {
            if (obj.hasOwnProperty(attr)) {
                let val: any = obj[attr];
                let valSym = sepSymbol;
                if (typeof val === "object") {
                    val = val.value;
                    valSym = val.separator;
                }
                coupleList.push(attr + valSym + SqlDB.typeVal(val));
            }
        }
        return coupleList;
    }
    public readonly dbName: string;
    public readonly db: Database;
    public printSQL: boolean = false;
    public debugSQL: boolean = false;
    public devResult: boolean = false;
    constructor(dbName: string) {
        this.dbName = dbName;
        this.db = new Database(this.dbName);
        verbose();
    }
    public runBySql(sql: string): Promise<void> {
        if (this.printSQL) {
            console.log(sql);
        }
        if (this.debugSQL) {
            debugger;
        }
        if (this.devResult) {
            return Promise.resolve();
        }
        return new Promise<void>((resolve, reject) => {
            this.db.run(sql, (err) => {
                if (err) {
                    reject(err);
                } else {
                    resolve();
                }
            });
        });
    }
    public getBySql(sql: string): Promise<Partial<TableData>> {
        if (this.printSQL) {
            console.log(sql);
        }
        if (this.debugSQL) {
            debugger;
        }
        if (this.devResult) {
            return Promise.resolve({});
        }
        return new Promise<Partial<TableData>>((resolve, reject) => {
            this.db.get(sql, (err, row: Partial<TableData>) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(row);
                }
            });
        });
    }
    public getAllBySql(sql: string): Promise<Array<Partial<TableData>>> {
        if (this.printSQL) {
            console.log(sql);
        }
        if (this.debugSQL) {
            debugger;
        }
        if (this.devResult) {
            return Promise.resolve([]);
        }
        return new Promise<Array<Partial<TableData>>>((resolve, reject) => {
            this.db.all(sql, (err, rows: Array<Partial<TableData>>) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(rows);
                }
            });
        });
    }
    public serialize(callback: () => void): this {
        this.db.serialize(() => {
            callback();
        });
        return this;
    }
    public parallelize(callback: () => void): this {
        this.db.parallelize(() => {
            callback();
        });
        return this;
    }
    public resetDevTool() {
        this.devResult = false;
        this.debugSQL = false;
        this.printSQL = false;
    }
}
